package com.himalayan.bear.controller;

import com.himalayan.bear.common.util.FileUtils;
import com.himalayan.bear.util.AESUtil;
import com.himalayan.bear.util.FileUtil;
import com.himalayan.bear.util.MD5Util;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/server")
public class FileUploadController extends BaseController {

    @ModelAttribute
    public String valid(String code) {
        System.out.println("ModelAttribute: " + code);
        if (code == null) {
            return null;
        }
        try {
            return AESUtil.Encrypt(code, AESUtil.CDKEY);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 文件下载
     *
     * @param fileName
     * @param request
     * @return
     */
    @RequestMapping("/fileDown")
    public ResponseEntity<byte[]> fileDown(String fileName, HttpServletRequest request) {
        if (StringUtils.isEmpty(fileName)) {
            return new ResponseEntity<>(null, null, HttpStatus.CREATED);
        }
        String path = request.getServletContext().getRealPath("/files/" + fileName);
        File file = new File(path); // 新建一个文件

        HttpHeaders headers = new HttpHeaders();//http头信息

        headers.setContentDispositionFormData("attachment", file.getName());
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

        try {
            return new ResponseEntity<>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseEntity<>(null, headers, HttpStatus.CREATED);
        }
    }

    /**
     * 页面跳转的上传
     *
     * @param file
     * @param mav
     * @param request
     * @return
     */
    @RequestMapping("/file")
    public ModelAndView upload(MultipartFile file, String pre, ModelAndView mav, HttpServletRequest request) {
        mav.setViewName("page/upload");
        if (file == null) {
            mav.addObject("message", "文件不能为空！");
            return mav;
        }
        Map<String, Object> result = upload("what the fuck ?!", pre, file, request, null);
        mav.addObject("message", result.get("message"));
        return mav;
    }

    /**
     * 文件上传主方法(ajax)
     *
     * @param code     用于验证的代码(现未启用)
     * @param pre      文件名的前缀, 用于区分文件夹(比如pre = aa/bb/cc, 服务器保存时会以这个格式创建文件夹目录)
     * @param file     文件实体
     * @param response 响应
     * @return
     */
    @RequestMapping("/data")
    public Map<String, Object> upload(@ModelAttribute String code, String pre,
                                      MultipartFile file,
                                      HttpServletRequest request,
                                      HttpServletResponse response) {
        System.out.println("code: " + code);
        System.out.println("pre: " + pre);
        if (file == null) {
            return null;
        }
        if (response != null) {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Access-Control-Allow-Origin", "*"); // 解决跨域
        }
        Map<String, Object> map = new HashMap<>();
        String fileName = file.getOriginalFilename();

        if (StringUtils.isEmpty(pre)) {
            Calendar calendar = Calendar.getInstance();
            int month = calendar.get(Calendar.MONTH) + 1;
            int date = calendar.get(Calendar.DATE);
            pre = calendar.get(Calendar.YEAR) + "/" + (month < 10 ? "0" + month : month) + "/" + (date < 10 ? "0" + date : date);
        }

        String absolutePath = request.getServletContext().getRealPath("/files/");
        File parent = new File(absolutePath + pre);

        boolean flag;

        if (!parent.exists()) {
            flag = parent.mkdirs();
        } else {
            flag = parent.exists();
        }

        File saveFile;

        String newFileName = FileUtil.getFileName(fileName);
        if (flag) {
            saveFile = new File(parent.getAbsolutePath() + File.separator + newFileName);
            try {
                String savePath = saveFile.getAbsolutePath();
                file.transferTo(saveFile);
                map.put("savePath", savePath);
                String path = request.getContextPath();
                /*String loadPath = request.getScheme() + "://"
                        + request.getServerName() + ":" + request.getServerPort()
                        + path + savePath.substring(savePath.indexOf("\\files\\")).replaceAll("\\\\", "/");*/
                String loadPath = savePath.substring(savePath.indexOf("\\files\\")).replaceAll("\\\\", "/");
                map.put("loadPath", loadPath);
                map.put("orgFileName", fileName);
                map.put("fileName", newFileName);
                map.put("fileSize", file.getSize());
                try {
                    String md5Code = MD5Util.MD5(saveFile);
                    map.put("code", md5Code);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                map.put("success", true);
                map.put("message", "上传成功 !");
            } catch (IOException e) {
                e.printStackTrace();
                map.put("success", false);
                map.put("message", "文件上传过程中出现异常 !");
            }
        } else {
            map.put("success", false);
            map.put("message", "父级文件夹创建失败 !");
        }
        return map;
    }
}
